<template>
    <div class="moveBox-root" style="" ref="moveBoxDom" @click="moveBox_ClickEvent">
        <slot></slot>
    </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, getCurrentInstance } from 'vue';

const props = defineProps({
    attr: {
        type: {},
        default: {},
        require: false,
    }
});
const emits = defineEmits(['move', 'moveend', 'movebegin']);

const curAttr = ref({});
const defaultAttr = () => {
    return {
        zIndex: [999, 9999], //高亮图层,0:其他被点击时,1:直接被点击时
        posi: [0, 0], //初始位置
    };
}


let state = 0;//0:静止,1:移动插值中

document.oncontextmenu = new Function("return false");


onMounted(() => {
    document.body.addEventListener('mousemove', box_MousemoveEvent);
    document.body.addEventListener('mouseup', box_MouseupEvent);

    // 对下面的第一个div元素进行挂载移动事件
    const arr = moveBoxDom.value.childNodes;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] instanceof HTMLElement) {
            arr[i].addEventListener('mousedown', box_MousedownEvent);
            break;
        }
    }

    setAttr(props.attr);
});

onBeforeUnmount(() => {
    document.body.removeEventListener('mousemove', box_MousemoveEvent);
    document.body.removeEventListener('mouseup', box_MouseupEvent);
})

const moveBox_ClickEvent = () => {
    if (state == 1) return;
    const curDom = moveBoxDom.value;
    const elem = document.querySelectorAll('.moveBox-root');
    for (let i = 0; i < elem.length; i++) {
        const element = elem[i];
        const { left, top } = element.getBoundingClientRect();
        const zIndex = element.dataset.zIndex.split(',');
        if (curDom != null && curDom == elem[i]) {
            //重复触发导致覆盖移动的动画
            element.setAttribute('style', `top:${top}px;left:${left}px;transition-duration:0s;z-index:${zIndex[1]};`);
        } else {
            element.setAttribute('style', `top:${top}px;left:${left}px;transition-duration:0s;z-index:${zIndex[0]};`);
        }
    }
}


//#region 移动逻辑
let isMove = true;//是否允许移动的状态(外部)
let moveState = ref(false);//正在移动的状态
let offset = [];
const moveBoxDom = ref();
let timeOut = null;
const box_MousedownEvent = (e) => {
    if (!isMove) return;
    if (e.button == 2) {
        offset = [e.offsetX, e.offsetY];
        moveState.value = true;
        emits('movebegin', offset);

        console.log(offset)

    }
}

const box_MousemoveEvent = (e) => {
    const { clientX, clientY } = e;
    if (moveState.value) {


        const l = clientX - offset[0];
        const t = clientY - offset[1];
        const posi = [l, t];
        moveBoxDom.value.setAttribute('style', `top:${t}px;left:${l}px;z-index:99999;`);
        curAttr.value.posi = posi;
        emits('move', posi);
    }
}
const box_MouseupEvent = (e) => {
    if (moveState.value) {
        const posi = curAttr.value.posi;
        moveState.value = false;
        move(posi[0], posi[1]);
        emits('moveend', posi);
    }
}
//#endregion

const move = (x, y, duration = 0.3) => {
    const { zIndex } = curAttr.value;
    curAttr.value.posi = [x, y];
    state = 1;
    moveBoxDom.value.setAttribute('style', `top:${y}px;left:${x}px;transition-duration:${duration}s;z-index:${zIndex[1]};`);
    if (duration >= 0) {
        if (timeOut) clearTimeout(timeOut);
        timeOut = setTimeout(() => {
            moveBoxDom.value.setAttribute('style', `top:${y}px;left:${x}px;z-index:${zIndex[0]};`);
            state = 0;
        }, duration * 1000);
    }
}

const setPosi = (x, y) => {
    curAttr.value.posi = [x, y];
}

const setIsMove = (move) => {
    isMove = move;
}

const setAttr = (rootAttr) => {
    rootAttr.id = getCurrentInstance().uid;
    Object.assign(curAttr.value, defaultAttr(), rootAttr);

    const dataSet = moveBoxDom.value.dataset;
    dataSet['zIndex'] = curAttr.value['zIndex'];
    move(curAttr.value.posi[0], curAttr.value.posi[1], 0);
}

const getRootDom = () => {
    return moveBoxDom.value;
}

const getUid = () => {
    return getCurrentInstance().uid;
}

defineExpose({
    move, setIsMove, setPosi, setAttr, getRootDom, getUid,
})

</script>

<style scoped lang="scss">
.moveBox-root {
    position: fixed;
    z-index: 999;
}
</style>
